﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PulseApp
{
    public class DTW
    {

        public static double getWarpDistBetween(TimeSeries tsI, TimeSeries tsJ) 
        {
            if (tsI.size() < tsJ.size())
                return getWarpDistBetween(tsJ, tsI);
            double[] lastCol = new double[tsJ.size()];
            double[] currCol = new double[tsJ.size()];
            int maxI = tsI.size() - 1;
            int maxJ = tsJ.size() - 1;
            currCol[0] = euclideanDist(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(0));
            for (int j = 1; j <= maxJ; j++)
                currCol[j] = currCol[j - 1] + euclideanDist(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(j));

            for (int i = 1; i <= maxI; i++) {
                double[] temp = lastCol;
                lastCol = currCol;
                currCol = temp;
                currCol[0] = lastCol[0] + euclideanDist(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(0));
                for (int j = 1; j <= maxJ; j++) {
                    double minGlobalCost = Math.Min(lastCol[j], Math.Min(lastCol[j - 1], currCol[j - 1]));
                    currCol[j] = minGlobalCost + euclideanDist(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(j));
                }

            }

            return currCol[maxJ];
        }



        private static double euclideanDist(double[] vector1, double[] vector2)
        {
            if (vector1.Length != vector2.Length)
                throw new Exception("ERROR:  cannot calculate the distance between vectors of different sizes.");
            double sqSum = 0.0D;
            for (int x = 0; x < vector1.Length; x++)
                sqSum += Math.Pow(vector1[x] - vector2[x], 2D);

            return Math.Pow(Math.Sqrt(sqSum), 2D);
        }
    }
}
